﻿using Coldairarrow.Entity.Base;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.Entity.Print;
using Coldairarrow.Entity.TD;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using Coldairarrow.Util.ClassLibrary;
using Coldairarrow.Util.Helper;
using EFCore.Sharding;
using Elasticsearch.Net;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using NPOI.POIFS.Crypt.Dsig;
using Org.BouncyCastle.Ocsp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.TD
{
    public partial class TD_InStorageBusiness : BaseBusiness<TD_InStorage>, ITD_InStorageBusiness, ITransientDependency
    {

        #region 外部接口



        #endregion

        #region 私有成员

        #endregion
        public async Task<PageResult<TD_InStorage>> GetDataListAsyncScrap(TD_InStoragePageInput input)
        {
            Expression<Func<TD_InStorage, Base_EnumItem, TD_Receiving, TD_InStorageDTO>> select = (a, b, c) => new TD_InStorageDTO
            {
                TypeName = b.Name,
                ReCode = c.Code
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_EnumItem>() on a.InType equals b.Code into ab
                    from b in ab.Where(u => u.EnumCode.Contains("InStorageType")).DefaultIfEmpty()
                    join c in Db.GetIQueryable<TD_Receiving>() on a.RecId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    select @select.Invoke(a, b, c);
            q = q
                .Include(i => i.Supplier)
                .Include(i => i.CreateUser)
                .Include(i => i.AuditUser)
                .Include(i => i.ReCode).Where(w => _operator.Property.DeptIds.Contains(w.StorId));
            var where = LinqHelper.True<TD_InStorage>();
            var search = input.Search;

            if (!search.Code.IsNullOrEmpty())
                where = where.And(w => w.Code.Contains(search.Code) || w.RefCode.Contains(search.Code));
            if (!search.InType.IsNullOrEmpty())
                where = where.And(w => w.InType == search.InType);
            if (!search.Rukuid.IsNullOrEmpty())
                where = where.And(w => w.Id.Contains(search.Rukuid));
            if (search.InStorTimeStart.HasValue)
                where = where.And(w => w.InStorTime >= search.InStorTimeStart.Value);
            if (search.InStorTimeEnd.HasValue)
                where = where.And(w => w.InStorTime <= search.InStorTimeEnd.Value);
            if (search.Status.HasValue)
                where = where.And(w => w.Status == search.Status.Value);
            q = q.Where(x => x.InType == "Product");
            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<PageResultData<inStorDetailDto>> inStorDetailDetail(PageInput<ProjectSummaryContionDTO> input)
        {
            string sql = @"SELECT
	sto.`Name` Warehouse,
	m.`Code` materialCode,
	m.`Name` MaterName,
	sum( a.Num ) Num,
	m.Spec materialSpce,
	IFNULL( m.Weight, 0 ) Weight,
	IFNULL( SUM( a.Num )* m.Weight, 0 )  materialWeight
FROM
	TD_InStorDetail AS a
	LEFT JOIN Base_Department AS sto ON a.StorId = sto.Id
	LEFT JOIN PB_Material AS m ON a.MaterialId = m.Id 
where 1=1 {0} {1} {2}
GROUP BY
	a.MaterialId,
	a.StorId
	";
            string time = "";
            string Strarea = "";
            string MatelName = "";
            if (!string.IsNullOrEmpty(input.Search.OrderTimeStart.ToString()) && !string.IsNullOrEmpty(input.Search.OrderTimeEnd.ToString()))
            {
                time = "  and a.CreateTime between   '" + Convert.ToDateTime(input.Search.OrderTimeStart).ToString("yyyy-MM-dd 00:00:00") + "'   and '" + Convert.ToDateTime(input.Search.OrderTimeEnd).ToString("yyyy-MM-dd 23:59:59") + "'";
            }
            if (!string.IsNullOrEmpty(input.Search.StrareaName))
            {
                Strarea = "and sto.Id = '" + input.Search.StrareaName + "'";
            }
            if (!string.IsNullOrEmpty(input.Search.MaterialNameOrCode))
            {
                MatelName = "  and (m.`Name` like '%" + input.Search.MaterialNameOrCode + "%' or   m.`Code` like '%" + input.Search.MaterialNameOrCode + "%') ";
            }

            sql = string.Format(sql, MatelName, Strarea, time);
            var res = await Db.GetListBySqlAsync<inStorDetailDto>(sql);
            #region   分页处理数据   有bug 没有按照主数据进行处理
            int pagecount;//总页数
            List<inStorDetailDto> listpro_down = res.ToList();//一个要分页的，类型数据集合，存储的是所有的数据
            List<inStorDetailDto> productes = new List<inStorDetailDto>();//用来存储要展示的数据
            int pagees = listpro_down.Count;//所有数据的总条数
                                            //计算总页数
            if (pagees % input.PageRows == 0)
            {
                pagecount = pagees / input.PageRows;
            }
            else
            {
                pagecount = (pagees / input.PageRows) + 1;
            }
            productes = listpro_down.Skip((input.PageIndex - 1) * input.PageRows).Take(input.PageRows).ToList();//分页的重点
            double? TotalQuantity = 0;
            double? TotalWeight = 0;
            for (int i = 0; i < res.Count; i++)
            {
                TotalQuantity += res[i].Num;
                TotalWeight += res[i].materialWeight;
            }
            return new PageResultData<inStorDetailDto> { Data = productes, Total = pagees, TotalQuantity = TotalQuantity.ToString(), TotalWeight = TotalWeight.ToString() };
            #endregion
        }

        /// <summary>
        /// 获取无码入库单的明细
        /// </summary>
        /// <param name="InStorageId">入库单Id</param>
        /// <returns></returns>
        public async Task<List<NoCodeInStorageDetailDTO>> GetInStorageDetailListAsync(string InStorageId)
        {
            Expression<Func<TD_InStorDetail, PB_Material, NoCodeInStorageDetailDTO>> select = (a, b) => new NoCodeInStorageDetailDTO
            {
                MaterialName = b.Name,
                MaterialSpec = b.Spec,
                MaterialCode = b.Code,
                IsProduct = b.IsProduct,
                ProductCode = b.ProductCode,
                IsStandard = b.IsStandard,
                PrintNums = a.Num
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in Db.GetIQueryable<TD_InStorDetail>().AsExpandable()
                    join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    select @select.Invoke(a, b);
            q = q.Where(x => x.InStorId == InStorageId);
            return await q.ToListAsync();
        }

        /// <summary>
        /// 无码入库单打印条码
        /// </summary>
        /// <param name="data">打印机Id</param>
        /// <param name="_mongodbOptions">mongo数据库连接</param>
        /// <returns></returns>
        public async Task PrintNoCodeInStorageDetailDataAsync(NoCodeInStorageDetailData data, MongoDBOptions _mongodbOptions)
        {
            //获取打印机信息
            PB_Printer pB_Printer = await Db.GetIQueryable<PB_Printer>().Where(x => x.Id == data.PrinterId).FirstOrDefaultAsync();
            //推送队列批次
            string timestamp = Guid.NewGuid().ToString("N");
            //实例化队列对象集合
            List<PrintQueue> printQueues = new List<PrintQueue>();
            //获取法人信息
            var deptdata = await _opdept.GetOperatorDept();
            //循环插入队列
            foreach (var item in data.noCodeInStorageDetailDTOs)
            {
                for (int i = 0; i < item.PrintNums; i++)
                {
                    PrintQueue pq = new PrintQueue();
                    pq.Id = IdHelper.GetId();
                    pq.No = item.MaterialId;
                    pq.Name = item.MaterialName;
                    pq.TypeName = item.MaterialSpec;
                    pq.Date = DateTime.Now.ToString("yyyy-MM-dd");
                    pq.Dept = deptdata.DeptName;
                    pq.QrCode = h_Material + "," + item.MaterialId;
                    pq.Type = Skill_Type.Statistics.ToString();
                    pq.Status = "0";
                    pq.Printer = data.PrinterId;
                    pq.IsProduct = item.IsProduct;
                    pq.Code = item.IsProduct == true ? item.ProductCode : item.MaterialCode;
                    pq.BatchNumber = timestamp;
                    pq.JobCount = item.PrintNums;
                    pq.ProjectName = "";
                    pq.BuildingNumberName = "";
                    pq.IsStandard = item.IsStandard == false ? 0 : 1;
                    printQueues.Add(pq);
                }
            }
            MongoDBHelper mongo = new MongoDBHelper(_mongodbOptions);
            //插入mongo队列
            await mongo.InsertManyAsync<PrintQueue>(PrintQueueCollection, printQueues);

        }

    }
}
